package org.lmind.rom.util;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;

public class HttpRemoteFile implements RemoteFile {
	
	private URL url;
	
	private HttpClient client = new HttpClient();
	
	private InputStream data;
	
	private long size = -1;

	public HttpRemoteFile(URL url) {
		super();
		this.url = url;
	}

	public void close() throws IOException {
		
	}

	public long getSize() throws IOException {
		
		if (size == -1) {
			GetMethod method = new GetMethod(url.toString());
			method.addRequestHeader("Range", "bytes=1-1");
			int status = client.executeMethod(method);
			if (HttpStatus.SC_PARTIAL_CONTENT != status) {
				throw new IOException();
			}
			Header header = method.getResponseHeader("Content-Range");
			if (header == null)
				throw new IOException("服务器不返回Content-Range");
			
			Pattern pattern = Pattern.compile("bytes (\\d+)-(\\d+)/(\\d+)");
			Matcher m = pattern.matcher(header.getValue());
			if (!m.find())
				throw new IOException("无法解析Content-Range");
			String totalSize = m.group(3);
			
			size = Long.valueOf(totalSize);
		}
		
		return size;
	}

	public InputStream openRead(long offset, long length) throws IOException {
		if (offset < -1 || length < -1)
			throw new IllegalArgumentException();
		if (offset != -1) {
			if (offset < 0 || offset > getSize())
				throw new IllegalArgumentException();
		}
		
		String range = "bytes=";
		if (offset >= 0) {
			range += offset + "-";
		}
		if (length >= 0) {
			range += (offset+length);
		}
		
		GetMethod method = new GetMethod(url.toString());
		if (!"bytes=".equals(range)) {
			method.addRequestHeader("Range", range);
		}
		if (HttpStatus.SC_PARTIAL_CONTENT != client.executeMethod(method)) {
			throw new IOException();
		}
		return method.getResponseBodyAsStream();
	}

}
